#include <iostream>
#include <vector>
#include "MyHash.hpp"
#include <ctime>

using namespace std;
using namespace close_hash;

// 整数查找
// void close_hash_test()
// {
//     // 时间种子
//     srand((unsigned int)time(nullptr));
//     HashTable<int, int> h;
//     int keyLen = 10;
//     vector<int> keyArr(keyLen);
    
//     for (int i = 0; i < keyLen; ++i)
//     {
//         int key = rand() % 10000, value = rand() % 1999;
//         keyArr[i] = key;
//         h.insert(make_pair(key, value));
//         /////展示阶段
//         cout << "-------------------------\n";
//         cout << "当前插入key-value: " << key << ": " << value << endl;
//         cout << "当前负载数: " << h.size() << endl;
//         cout << "当前容量: " << h.capacity() << endl;
//         cout << "当前负载因子: " << h.loadfactor() << endl;
//         cout << "-------------------------\n"; 
//     }

//     for (int i = 0; i < keyLen; ++i)
//     {
//         HashElem<int, int>* elem = h.find(keyArr[i]);
//         if (elem == nullptr)
//         {
//             cout << "哈希表存在问题，请检查后测试！" << endl;
//             break;
//         }
//         cout << "key: " << elem->kv.first << " value: " << elem->kv.second << endl;
//     }
// }

// 字符串检查
// void close_hash_test()
// {
//     // 时间种子
//     srand((unsigned int)time(nullptr));
//     HashTable<string, int> h;
//     int keyLen = 20;
//     vector<string> keyArr(keyLen);
    
//     for (int i = 0; i < keyLen; ++i)
//     {
//         // 生成1~6长度的随机字符串作为key进行测试
//         int num = rand() % 6 + 1;
//         string str;
//         for (int i = 0; i < num; ++i)
//         {
//             int fes = rand() % 26;
//             str += ('a' + fes);
//         }

//         int value = rand() % 1999;
//         keyArr[i] = str;
//         h.insert(make_pair(keyArr[i], value));
//         /////展示阶段
//         cout << "-------------------------\n";
//         cout << "当前插入key-value: " << str << ": " << value << endl;
//         cout << "当前负载数: " << h.size() << endl;
//         cout << "当前容量: " << h.capacity() << endl;
//         cout << "当前负载因子: " << h.loadfactor() << endl;
//         cout << "-------------------------\n"; 
//     }

//     for (int i = 0; i < keyLen; ++i)
//     {
//         HashElem<string, int>* elem = h.find(keyArr[i]);
//         if (elem == nullptr)
//         {
//             cout << "哈希表存在问题，请检查后测试！" << endl;
//             break;
//         }
//         cout << "key: " << elem->kv.first << " value: " << elem->kv.second << endl;
//     }
// }

// 实际比较查找时间
void close_hash_test()
{
    // 时间种子
    srand((unsigned int)time(nullptr));

    HashTable<string, int> h;
    vector<pair<string, int>> strArr;

    int keyLen = 20000;
    strArr.resize(keyLen);

    vector<string> keyArr(keyLen);
    
    for (int i = 0; i < keyLen; ++i)
    {
        // 生成1~6长度的随机字符串作为key进行测试
        int num = rand() % 6 + 1;
        string str;
        for (int i = 0; i < num; ++i)
        {
            int fes = rand() % 26;
            str += ('a' + fes);
        }

        int value = rand() % 1999;
        keyArr[i] = str;
        h.insert(make_pair(keyArr[i], value));
        strArr[i] = make_pair(keyArr[i], value);
    }

    pair<string, int> kv;

    // 随机在数组内查找
    clock_t time1, time2;
    clock_t time_strArr = 0, time_closeHash = 0;

    int n = keyLen;
    vector<bool> keyexist1(keyLen, false);

    // 普通数组On遍历
    while (n)
    {
        int num = rand() % keyLen;
        while (keyexist1[num])
        {
            // 找到没有被使用的
            num = rand() % keyLen;
        }
        keyexist1[num] = true;
        --n;  // 可用下标数减一

        time1 = clock();
        for(int i = 0; i < keyLen; ++i)
        {
            if (strArr[i].first == keyArr[num]){
                kv = strArr[i];
                break;
            }
        }
        time2 = clock();
        time_strArr += (time2 - time1);
        // cout << "key-value: " << kv.first << ": " << kv.second << endl;
    }

    // cout << endl << endl;
    // 闭散列哈希表查找
    n = keyLen;
    vector<bool> keyexist2(keyLen, false);
    while (n)
    {
        int num = rand() % keyLen;
        while (keyexist2[num])
        {
            // 找到没有被使用的
            num = rand() % keyLen;
        }
        keyexist2[num] = true;
        --n;  // 可用下标数减一

        HashElem<string, int>* temp;
        time1 = clock();
        temp = h.find(keyArr[num]);
        time2 = clock();
        time_closeHash += (time2 - time1);
        kv= temp->kv;
        // cout << "key-value: " << kv.first << ": " << kv.second << endl;
    }

    cout << "----------------------------\n";
    cout << "time_strArr: " << time_strArr << endl;
    cout << "time_closeHash: " << time_closeHash << endl;
}

int main()
{
    close_hash_test();
    return 0;
}